home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / hash < prev    next >
Encoding:
Text File  |  1988-04-18  |  4.4 KB  |  148 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *              hash.c
  10.  */
  11.  
  12. #include        "tex.h"
  13. #include        "cmds.h"
  14. #include        "heap.h"
  15. #include        "box.h"
  16. #include        "scan.h"
  17. #include        "eq.h"
  18. #include        "io.h"
  19. #include        "math.h"
  20. #include        "boxlists.h"
  21. #include        "str.h"
  22. #include        "error.h"
  23. #include        "hash.h"
  24.  
  25. twoh    hash[UNDEFINED_CONTROL_SEQUENCE+1];
  26. ptr             hash_used = FROZEN_CONTROL_SEQUENCE;
  27. bool    no_new_control_sequence = TRUE;
  28. int             cs_count = 0;
  29.  
  30. ptr
  31. id_lookup (j, l)
  32.         int             j;
  33.         int             l;
  34. {
  35.         int             h;
  36.         int             k;
  37.         ptr             p;
  38.  
  39.         h = buffer[j];
  40.         for (k = j + 1; k < j + l; incr(k)) {
  41.                 h = h + h + buffer[k];
  42.                 while (h >= HASH_PRIME)
  43.                         h -= HASH_PRIME;
  44.         }
  45.         for (p = h + HASH_BASE; ; p = next(p)) {
  46.                 if (text(p) > 0 && length(text(p)) == l)
  47.                         if (str_eq_buf(text(p), j))
  48.                                 return p;
  49.                 if (next(p) == 0) {
  50.                         if (no_new_control_sequence)
  51.                                 return UNDEFINED_CONTROL_SEQUENCE;
  52.                         if (text(p) > 0) {
  53.                                 do
  54.                                         if (hash_is_full)
  55.                                                 overflow("hash size", HASH_SIZE);
  56.                                         else decr(hash_used);
  57.                                 while (text(hash_used) != 0);
  58.                                 next(p) = hash_used;
  59.                                 p = hash_used;
  60.                         }
  61.                         str_room(l);
  62.                         for (k = j; k < j + l; incr(k))
  63.                                 append_char(buffer[k]);
  64.                         text(p) = make_string();
  65. #ifdef STAT
  66.                         incr(cs_count);
  67. #endif
  68.                         return p;
  69.                 }
  70.         }
  71. }
  72.  
  73. print_cs (p)
  74.         ptr             p;
  75. {       
  76.         if (p < HASH_BASE) {
  77.                 if (p >= SINGLE_BASE) {
  78.                         if (p == NULL_CS) {
  79.                                 print_esc("csname");
  80.                                 print_esc("endcsname");
  81.                         } else {
  82.                                 print_esc(""); 
  83.                                 print_str(p - SINGLE_BASE); 
  84.                                 if (cat_code(p - SINGLE_BASE) == LETTER)
  85.                                         print_char(' ');
  86.                         }
  87.                 } else if (p < ACTIVE_BASE)
  88.                         print_esc("IMPOSSIBLE.");
  89.                 else print_str(p - ACTIVE_BASE);
  90.         } else if (p >= UNDEFINED_CONTROL_SEQUENCE)
  91.                 print_esc("IMPOSSIBLE.");
  92.         else if (text(p) < 0 || text(p) >= str_ptr)
  93.                 print_esc("NONEXISTENT.");
  94.         else {
  95.                 print_esc("");
  96.                 slow_print(text(p));
  97.                 print_char(' ');
  98.         }
  99. }
  100.  
  101. sprint_cs (p)
  102.         ptr             p;
  103. {
  104.         if (p < HASH_BASE) {
  105.                 if (p < SINGLE_BASE)
  106.                         print_str(p - ACTIVE_BASE);
  107.                 else if (p < NULL_CS) {
  108.                         print_esc("");
  109.                         print_str(p - SINGLE_BASE);
  110.                 } else {
  111.                         print_esc("csname");
  112.                         print_esc("endcsname");
  113.                 }
  114.         } else {
  115.                 print_esc("");
  116.                 slow_print(text(p));
  117.         }
  118. }
  119.  
  120. #ifdef INIT
  121. primitive (s, c, o)
  122.         char*   s;
  123.         qword   c;
  124.         hword   o;
  125. {
  126.         int             j;
  127.         int             k;
  128.         int             l;
  129.         str             new_str;
  130.  
  131.         if (s[1] == NUL)
  132.                 cur_val = s[0] + SINGLE_BASE;
  133.         else {
  134.                 new_str = make_string_given(s);
  135.                 k = str_start[new_str];
  136.                 l = length(new_str);
  137.                 for (j = 0; j < l; incr(j))
  138.                         buffer[j] = str_pool[k + j];
  139.                 cur_val = id_lookup(0, l);
  140.                 flush_string();
  141.                 text(cur_val) = new_str;
  142.         }
  143.         eq_level(cur_val) = LEVEL_ONE;
  144.         eq_type(cur_val) = c;
  145.         equiv(cur_val) = o;
  146. }
  147. #endif
  148.